import pygame
import sys
import json
from typing import List, Tuple, Optional
import maze_generator
import clue_generator
import Lock

# 颜色定义
COLORS = {
    'white': (255, 255, 255),
    'black': (0, 0, 0),
    'gray': (128, 128, 128),
    'light_gray': (200, 200, 200),
    'dark_gray': (64, 64, 64),
    'blue': (100, 150, 255),
    'green': (100, 255, 100),
    'red': (255, 100, 100),
    'yellow': (255, 255, 100),
    'orange': (255, 165, 0),
    'purple': (128, 0, 128)
}

class ContextMenu:
    def __init__(self, x, y, items):
        self.x = x
        self.y = y
        self.items = items  # [(text, action), ...]
        self.width = 120
        self.height = len(items) * 25
        self.font = pygame.font.Font(None, 20)
        self.visible = True
        self.hovered_item = -1
        
    def draw(self, screen):
        if not self.visible:
            return
            
        # 绘制菜单背景
        menu_rect = pygame.Rect(self.x, self.y, self.width, self.height)
        pygame.draw.rect(screen, COLORS['white'], menu_rect)
        pygame.draw.rect(screen, COLORS['black'], menu_rect, 1)
        
        # 绘制菜单项
        for i, (text, action) in enumerate(self.items):
            item_rect = pygame.Rect(self.x, self.y + i * 25, self.width, 25)
            
            # 高亮悬停项
            if i == self.hovered_item:
                pygame.draw.rect(screen, COLORS['blue'], item_rect)
                text_color = COLORS['white']
            else:
                text_color = COLORS['black']
            
            # 绘制文本
            text_surface = self.font.render(text, True, text_color)
            text_x = self.x + 10
            text_y = self.y + i * 25 + 5
            screen.blit(text_surface, (text_x, text_y))
    
    def handle_event(self, event):
        if not self.visible:
            return None
            
        if event.type == pygame.MOUSEMOTION:
            mouse_x, mouse_y = event.pos
            self.hovered_item = -1
            
            # 检查鼠标是否在菜单项上
            for i in range(len(self.items)):
                item_rect = pygame.Rect(self.x, self.y + i * 25, self.width, 25)
                if item_rect.collidepoint(mouse_x, mouse_y):
                    self.hovered_item = i
                    break
        
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = event.pos
            
            # 检查是否点击了菜单项
            for i, (text, action) in enumerate(self.items):
                item_rect = pygame.Rect(self.x, self.y + i * 25, self.width, 25)
                if item_rect.collidepoint(mouse_x, mouse_y):
                    self.visible = False
                    return action
            
            # 点击菜单外部，关闭菜单
            menu_rect = pygame.Rect(self.x, self.y, self.width, self.height)
            if not menu_rect.collidepoint(mouse_x, mouse_y):
                self.visible = False
        
        return None

class Button:
    def __init__(self, x: int, y: int, width: int, height: int, text: str, 
                 bg_color: Tuple[int, int, int] = COLORS['light_gray'],
                 text_color: Tuple[int, int, int] = COLORS['black'],
                 font_size: int = 24):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.bg_color = bg_color
        self.text_color = text_color
        self.font = pygame.font.Font(None, font_size)
        self.hovered = False
        
    def draw(self, screen):
        color = COLORS['blue'] if self.hovered else self.bg_color
        pygame.draw.rect(screen, color, self.rect)
        pygame.draw.rect(screen, COLORS['black'], self.rect, 2)
        
        text_surface = self.font.render(self.text, True, self.text_color)
        text_rect = text_surface.get_rect(center=self.rect.center)
        screen.blit(text_surface, text_rect)
    
    def handle_event(self, event):
        if event.type == pygame.MOUSEMOTION:
            self.hovered = self.rect.collidepoint(event.pos)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if self.rect.collidepoint(event.pos):
                return True
        return False

class InputBox:
    def __init__(self, x: int, y: int, width: int, height: int, 
                 placeholder: str = "", max_length: int = 10, 
                 numeric_only: bool = False):
        self.rect = pygame.Rect(x, y, width, height)
        self.placeholder = placeholder
        self.text = ""
        self.max_length = max_length
        self.numeric_only = numeric_only
        self.active = False
        self.font = pygame.font.Font(None, 32)
        self.cursor_visible = True
        self.cursor_timer = 0
        self.context_menu = None  # 右键菜单
        
    def draw(self, screen):
        color = COLORS['white'] if self.active else COLORS['light_gray']
        pygame.draw.rect(screen, color, self.rect)
        pygame.draw.rect(screen, COLORS['blue'] if self.active else COLORS['black'], self.rect, 2)
        
        display_text = self.text if self.text else self.placeholder
        text_color = COLORS['black'] if self.text else COLORS['gray']
        
        text_surface = self.font.render(display_text, True, text_color)
        screen.blit(text_surface, (self.rect.x + 5, self.rect.y + 5))
        
        # 绘制光标
        if self.active and self.cursor_visible:
            cursor_x = self.rect.x + 5 + self.font.size(self.text)[0]
            pygame.draw.line(screen, COLORS['black'], 
                           (cursor_x, self.rect.y + 5), 
                           (cursor_x, self.rect.y + self.rect.height - 5), 2)
        
        # 绘制右键菜单
        if self.context_menu and self.context_menu.visible:
            self.context_menu.draw(screen)
    
    def handle_event(self, event):
        # 处理右键菜单事件
        if self.context_menu and self.context_menu.visible:
            action = self.context_menu.handle_event(event)
            if action:
                self._execute_menu_action(action)
                return None
        
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左键
                self.active = self.rect.collidepoint(event.pos)
                # 关闭菜单
                if self.context_menu:
                    self.context_menu.visible = False
            elif event.button == 3 and self.active:  # 右键且输入框激活
                self._show_context_menu(event.pos)
                
        elif event.type == pygame.KEYDOWN and self.active:
            if event.key == pygame.K_BACKSPACE:
                self.text = self.text[:-1]
            elif event.key == pygame.K_DELETE:
                # Delete键：清空所有文本
                self.text = ""
            elif event.key == pygame.K_RETURN:
                return 'enter'
            elif event.key == pygame.K_a and pygame.key.get_pressed()[pygame.K_LCTRL]:
                # Ctrl+A 全选 (这里我们可以在视觉上表示全选，但由于简单起见，暂时不实现)
                # 可以在未来版本中添加选择功能
                pass
            elif event.key == pygame.K_v and pygame.key.get_pressed()[pygame.K_LCTRL]:
                # Ctrl+V 粘贴功能
                self._paste_text()
            else:
                char = event.unicode
                if self.numeric_only and not char.isdigit():
                    return None
                if len(self.text) < self.max_length and char.isprintable():
                    self.text += char
        return None
    
    def _show_context_menu(self, mouse_pos):
        """显示右键菜单"""
        menu_items = [
            ("Paste", "paste"),
            ("Clear All", "clear"),
            ("Copy", "copy"),
            ("Select All", "select_all")
        ]
        
        # 确保菜单不会超出屏幕边界
        menu_x = mouse_pos[0]
        menu_y = mouse_pos[1]
        
        # 简单边界检查（假设屏幕是800x600）
        if menu_x + 120 > 800:
            menu_x = 800 - 120
        if menu_y + len(menu_items) * 25 > 600:
            menu_y = 600 - len(menu_items) * 25
        
        self.context_menu = ContextMenu(menu_x, menu_y, menu_items)
    
    def _execute_menu_action(self, action):
        """执行菜单动作"""
        if action == "paste":
            self._paste_text()
        elif action == "clear":
            self.text = ""
        elif action == "copy":
            self._copy_text()
        elif action == "select_all":
            # 由于简单实现，这里只是将光标移到末尾
            pass
    
    def _paste_text(self):
        """粘贴文本"""
        try:
            clipboard_text = self.get_clipboard_text()
            if clipboard_text:
                # 过滤掉换行符和其他不需要的字符
                clipboard_text = clipboard_text.replace('\n', '').replace('\r', '').strip()
                
                # 如果是数字输入框，只保留数字
                if self.numeric_only:
                    clipboard_text = ''.join(filter(str.isdigit, clipboard_text))
                
                # 检查长度限制
                remaining_space = self.max_length - len(self.text)
                if remaining_space > 0:
                    paste_text = clipboard_text[:remaining_space]
                    self.text += paste_text
        except Exception as e:
            print(f"Paste failed: {e}")
    
    def _copy_text(self):
        """复制文本到剪贴板"""
        if self.text:
            try:
                self.set_clipboard_text(self.text)
                print(f"Copied: '{self.text}'")
            except Exception as e:
                print(f"Copy failed: {e}")
    
    def set_clipboard_text(self, text):
        """设置剪贴板文本"""
        try:
            import subprocess
            import sys
            
            if sys.platform == 'darwin':  # macOS
                process = subprocess.Popen(['pbcopy'], stdin=subprocess.PIPE, text=True)
                process.communicate(input=text)
            elif sys.platform == 'win32':  # Windows
                process = subprocess.Popen(['clip'], stdin=subprocess.PIPE, text=True)
                process.communicate(input=text)
            elif sys.platform.startswith('linux'):  # Linux
                try:
                    process = subprocess.Popen(['xclip', '-selection', 'clipboard'], 
                                             stdin=subprocess.PIPE, text=True)
                    process.communicate(input=text)
                except FileNotFoundError:
                    process = subprocess.Popen(['xsel', '--clipboard', '--input'], 
                                             stdin=subprocess.PIPE, text=True)
                    process.communicate(input=text)
        except Exception as e:
            print(f"Failed to set clipboard: {e}")
    
    def get_clipboard_text(self):
        """获取剪贴板文本"""
        try:
            # 优先使用系统命令获取剪贴板内容
            import subprocess
            import sys
            
            if sys.platform == 'darwin':  # macOS
                result = subprocess.run(['pbpaste'], capture_output=True, text=True, timeout=1)
                if result.returncode == 0:
                    return result.stdout
            elif sys.platform == 'win32':  # Windows
                result = subprocess.run(['powershell', '-command', 'Get-Clipboard'], 
                                      capture_output=True, text=True, timeout=1)
                if result.returncode == 0:
                    return result.stdout.strip()
            elif sys.platform.startswith('linux'):  # Linux
                # 尝试xclip
                try:
                    result = subprocess.run(['xclip', '-selection', 'clipboard', '-o'], 
                                          capture_output=True, text=True, timeout=1)
                    if result.returncode == 0:
                        return result.stdout
                except FileNotFoundError:
                    # 如果xclip不可用，尝试xsel
                    result = subprocess.run(['xsel', '--clipboard', '--output'], 
                                          capture_output=True, text=True, timeout=1)
                    if result.returncode == 0:
                        return result.stdout
        except Exception as e:
            print(f"System clipboard access failed: {e}")
        
        # 备选方案：尝试使用tkinter（在独立进程中）
        try:
            import subprocess
            import sys
            
            # 创建一个独立的Python进程来访问tkinter
            python_code = '''
import tkinter as tk
try:
    root = tk.Tk()
    root.withdraw()
    clipboard_text = root.clipboard_get()
    root.destroy()
    print(clipboard_text, end="")
except:
    pass
'''
            result = subprocess.run([sys.executable, '-c', python_code], 
                                  capture_output=True, text=True, timeout=2)
            if result.returncode == 0 and result.stdout:
                return result.stdout
        except Exception as e:
            print(f"Tkinter clipboard access failed: {e}")
        
        return ""
    
    def update(self, dt):
        self.cursor_timer += dt
        if self.cursor_timer >= 500:  # 500ms 闪烁周期
            self.cursor_visible = not self.cursor_visible
            self.cursor_timer = 0

class GameGUI:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((800, 600))
        pygame.display.set_caption("Maze Game Setup")
        self.clock = pygame.time.Clock()
        self.font_large = pygame.font.Font(None, 48)
        self.font_medium = pygame.font.Font(None, 32)
        self.font_small = pygame.font.Font(None, 24)
        
        # 状态管理
        self.current_screen = "welcome"
        self.maze_size = 15
        self.password = ""
        self.password_hash = ""
        self.clues = []
        self.all_clues = []  # 添加 all_clues 属性初始化
        self.selected_clues = []
        self.load_mode = False  # 是否从文件加载模式
        self.loaded_data = None  # 加载的数据
        
        # 控件
        self.buttons = {}
        self.input_boxes = {}
        self.setup_controls()
        
    def setup_controls(self):
        """设置各种控件"""
        # 欢迎界面按钮
        self.buttons['start'] = Button(300, 280, 200, 50, "Create New Maze", COLORS['green'])
        self.buttons['load'] = Button(300, 340, 200, 50, "Load from JSON", COLORS['blue'])
        self.buttons['quit'] = Button(300, 400, 200, 50, "Quit Game", COLORS['red'])
        
        # 迷宫尺寸选择按钮
        sizes = [7, 9, 11, 13, 15, 17]
        for i, size in enumerate(sizes):
            x = 150 + (i % 3) * 200
            y = 200 + (i // 3) * 80
            self.buttons[f'size_{size}'] = Button(x, y, 120, 60, f"{size}x{size}", COLORS['light_gray'])
        
        self.buttons['size_next'] = Button(350, 400, 100, 50, "Next", COLORS['green'])
        
        # 密码输入
        self.input_boxes['password'] = InputBox(300, 250, 200, 40, "Enter 3-digit password", 3, True)
        self.buttons['password_next'] = Button(350, 320, 100, 50, "Next", COLORS['green'])
        
        # 文件路径输入
        self.input_boxes['file_path'] = InputBox(200, 250, 400, 40, "Enter JSON file path (e.g., input.json)", 100, False)
        self.buttons['file_load'] = Button(350, 320, 100, 50, "Load", COLORS['green'])
        self.buttons['file_back'] = Button(250, 320, 80, 50, "Back", COLORS['gray'])
        
        # 线索选择
        self.buttons['clue_next'] = Button(350, 500, 100, 50, "Start Game", COLORS['green'])
        
    def draw_welcome_screen(self):
        """绘制欢迎界面"""
        self.screen.fill(COLORS['white'])
        
        # 标题
        title_text = self.font_large.render("Maze Adventure Game", True, COLORS['black'])
        title_rect = title_text.get_rect(center=(400, 150))
        self.screen.blit(title_text, title_rect)
        
        # 描述
        desc_lines = [
            "Welcome to the Maze Adventure Game!"
        ]
        
        for i, line in enumerate(desc_lines):
            text = self.font_small.render(line, True, COLORS['dark_gray'])
            text_rect = text.get_rect(center=(400, 200 + i * 25))
            self.screen.blit(text, text_rect)
        
        self.buttons['start'].draw(self.screen)
        self.buttons['load'].draw(self.screen)
        self.buttons['quit'].draw(self.screen)
    
    def draw_maze_size_screen(self):
        """绘制迷宫尺寸选择界面"""
        self.screen.fill(COLORS['white'])
        
        title_text = self.font_large.render("Select Maze Size", True, COLORS['black'])
        title_rect = title_text.get_rect(center=(400, 100))
        self.screen.blit(title_text, title_rect)
        
        info_text = self.font_medium.render(f"Current Selection: {self.maze_size}x{self.maze_size}", True, COLORS['blue'])
        info_rect = info_text.get_rect(center=(400, 150))
        self.screen.blit(info_text, info_rect)
        
        # 绘制尺寸按钮
        sizes = [7, 9, 11, 13, 15, 17]
        for size in sizes:
            button = self.buttons[f'size_{size}']
            if size == self.maze_size:
                button.bg_color = COLORS['yellow']
            else:
                button.bg_color = COLORS['light_gray']
            button.draw(self.screen)
        
        self.buttons['size_next'].draw(self.screen)
    
    def draw_password_screen(self):
        """绘制密码输入界面"""
        self.screen.fill(COLORS['white'])
        
        title_text = self.font_large.render("Set Password", True, COLORS['black'])
        title_rect = title_text.get_rect(center=(400, 150))
        self.screen.blit(title_text, title_rect)
        
        info_text = self.font_medium.render("Please enter a 3-digit password:", True, COLORS['black'])
        info_rect = info_text.get_rect(center=(400, 200))
        self.screen.blit(info_text, info_rect)
        
        self.input_boxes['password'].draw(self.screen)
        
        if len(self.password) == 3:
            self.buttons['password_next'].draw(self.screen)
        
        # 显示输入提示
        if len(self.password) < 3:
            hint_text = self.font_small.render(f"Entered {len(self.password)}/3 digits", True, COLORS['gray'])
            hint_rect = hint_text.get_rect(center=(400, 300))
            self.screen.blit(hint_text, hint_rect)
    
    def draw_clue_selection_screen(self):
        """绘制线索选择界面"""
        self.screen.fill(COLORS['white'])
        
        title_text = self.font_large.render("Select Clues", True, COLORS['black'])
        title_rect = title_text.get_rect(center=(400, 80))
        self.screen.blit(title_text, title_rect)
        
        info_text = self.font_medium.render(f"Password: {self.password} (encrypted)", True, COLORS['blue'])
        info_rect = info_text.get_rect(center=(400, 120))
        self.screen.blit(info_text, info_rect)
        
        # 显示可用线索
        clue_text = self.font_medium.render("Available Clues (select 1-3):", True, COLORS['black'])
        clue_rect = clue_text.get_rect(center=(400, 160))
        self.screen.blit(clue_text, clue_rect)
        
        # 绘制线索选项
        for i, clue in enumerate(self.clues):
            y = 200 + i * 40
            clue_str = str(clue)
            
            # 检查是否被选中
            is_selected = clue in self.selected_clues
            bg_color = COLORS['green'] if is_selected else COLORS['light_gray']
            
            # 绘制线索框
            clue_rect = pygame.Rect(50, y, 700, 35)
            pygame.draw.rect(self.screen, bg_color, clue_rect)
            pygame.draw.rect(self.screen, COLORS['black'], clue_rect, 2)
            
            # 绘制线索文本
            text = self.font_small.render(f"{i+1}. {clue_str}", True, COLORS['black'])
            self.screen.blit(text, (clue_rect.x + 10, clue_rect.y + 8))
            
            # 存储点击区域
            if f'clue_{i}' not in self.buttons:
                self.buttons[f'clue_{i}'] = Button(clue_rect.x, clue_rect.y, clue_rect.width, clue_rect.height, "", bg_color)
            else:
                self.buttons[f'clue_{i}'].rect = clue_rect
                self.buttons[f'clue_{i}'].bg_color = bg_color
        
        # 显示选择状态
        status_text = f"Selected {len(self.selected_clues)} clues"
        status_surface = self.font_medium.render(status_text, True, COLORS['blue'])
        status_rect = status_surface.get_rect(center=(400, 450))
        self.screen.blit(status_surface, status_rect)
        
        # 显示开始按钮（需要至少选择1条线索）
        if len(self.selected_clues) >= 1:
            self.buttons['clue_next'].draw(self.screen)
    
    def draw_file_path_screen(self):
        """绘制文件路径输入界面"""
        self.screen.fill(COLORS['white'])
        
        title_text = self.font_large.render("Load from JSON File", True, COLORS['black'])
        title_rect = title_text.get_rect(center=(400, 150))
        self.screen.blit(title_text, title_rect)
        
        info_text = self.font_medium.render("Enter the path to your JSON file:", True, COLORS['black'])
        info_rect = info_text.get_rect(center=(400, 200))
        self.screen.blit(info_text, info_rect)
        
        self.input_boxes['file_path'].draw(self.screen)
        
        # 显示按钮
        if len(self.input_boxes['file_path'].text.strip()) > 0:
            self.buttons['file_load'].draw(self.screen)
        
        self.buttons['file_back'].draw(self.screen)
        
        # 显示文件格式说明
        format_lines = [
            "JSON file should contain:",
            '{"maze": [[...]], "L": "password_hash", "C": [...clues...]}',
            "",
            "Input methods:",
            "Type directly, Ctrl+V paste, or right-click for menu"
        ]
        
        for i, line in enumerate(format_lines):
            if line == "":
                continue
            text_color = COLORS['dark_gray'] if i == 0 or i == 3 else COLORS['gray']
            font_size = self.font_small if i < 3 else self.font_small
            text = font_size.render(line, True, text_color)
            line_y = 380 + (i if i < 3 else i-1) * 20  # 跳过空行
            text_rect = text.get_rect(center=(400, line_y))
            self.screen.blit(text, text_rect)
    
    def handle_welcome_events(self, event):
        """处理欢迎界面事件"""
        if self.buttons['start'].handle_event(event):
            self.current_screen = "maze_size"
            return
        if self.buttons['load'].handle_event(event):
            self.current_screen = "file_path"
            return
        if self.buttons['quit'].handle_event(event):
            return "quit"
    
    def handle_maze_size_events(self, event):
        """处理迷宫尺寸选择事件"""
        sizes = [7, 9, 11, 13, 15, 17]
        for size in sizes:
            if self.buttons[f'size_{size}'].handle_event(event):
                self.maze_size = size
                return
        
        if self.buttons['size_next'].handle_event(event):
            self.current_screen = "password"
            return
    
    def handle_password_events(self, event):
        """处理密码输入事件"""
        result = self.input_boxes['password'].handle_event(event)
        self.password = self.input_boxes['password'].text
        
        if (result == 'enter' or self.buttons['password_next'].handle_event(event)) and len(self.password) == 3:
            # 生成密码哈希
            from Lock import PasswordLock
            lock = PasswordLock()
            self.password_hash = lock.hash_password(self.password)
            
            # 生成线索
            self.clues = clue_generator.generate_clues(self.password)
            self.all_clues = self.clues.copy()  # 保存所有生成的线索
            self.current_screen = "clue_selection"
            return
    
    def handle_clue_selection_events(self, event):
        """处理线索选择事件"""
        # 处理线索点击
        for i in range(len(self.clues)):
            if f'clue_{i}' in self.buttons and self.buttons[f'clue_{i}'].handle_event(event):
                clue = self.clues[i]
                if clue in self.selected_clues:
                    self.selected_clues.remove(clue)
                elif len(self.selected_clues) < 3:
                    self.selected_clues.append(clue)
                return
        
        if self.buttons['clue_next'].handle_event(event) and len(self.selected_clues) >= 1:
            return "start_game"
    
    def handle_file_path_events(self, event):
        """处理文件路径输入事件"""
        result = self.input_boxes['file_path'].handle_event(event)
        
        if self.buttons['file_back'].handle_event(event):
            self.current_screen = "welcome"
            return
        
        if (result == 'enter' or self.buttons['file_load'].handle_event(event)) and len(self.input_boxes['file_path'].text.strip()) > 0:
            file_path = self.input_boxes['file_path'].text.strip()
            if self.load_json_file(file_path):
                return "start_game"
    
    def load_json_file(self, file_path):
        """加载JSON文件"""
        import os
        import json
        
        try:
            # 检查文件是否存在
            if not os.path.exists(file_path):
                print(f"Error: File '{file_path}' not found!")
                return False
            
            # 加载JSON文件
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            # 验证必需字段 - 只有maze是必需的
            if 'maze' not in data:
                print("Error: Missing required field 'maze' in JSON file!")
                return False
            
            # 验证迷宫格式
            maze = data['maze']
            if not isinstance(maze, list) or len(maze) == 0:
                print("Error: Invalid maze format!")
                return False
            
            for row in maze:
                if not isinstance(row, list):
                    print("Error: Invalid maze row format!")
                    return False
            
            # L和C字段是可选的
            has_password = 'L' in data and data['L']
            has_clues = 'C' in data and data['C']
            
            # 如果有线索但没有密码，或有密码但没有线索，给出警告
            if has_clues and not has_password:
                print("Warning: Clues found but no password hash. Puzzle solving will be skipped.")
            elif has_password and not has_clues:
                print("Warning: Password hash found but no clues. Puzzle solving will be skipped.")
            
            # 验证线索格式（如果存在）
            if has_clues:
                clues = data['C']
                if not isinstance(clues, list):
                    print("Error: Clues must be a list!")
                    return False
            
            # 设置加载模式数据
            self.load_mode = True
            self.loaded_data = data
            
            print(f"Successfully loaded JSON file: {file_path}")
            print(f"Maze size: {len(maze)}x{len(maze[0])}")
            if has_password and has_clues:
                print(f"Number of clues: {len(data['C'])}")
                print("Puzzle solving enabled")
            else:
                print("Puzzle solving disabled (missing L or C fields)")
            
            return True
            
        except json.JSONDecodeError as e:
            print(f"Error: Invalid JSON format - {e}")
            return False
        except Exception as e:
            print(f"Error loading file: {e}")
            return False
    
    def run(self):
        """运行GUI主循环"""
        running = True
        
        while running:
            dt = self.clock.tick(60)
            
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return None
                
                # 优先处理输入框事件（包括右键菜单）
                for input_box in self.input_boxes.values():
                    if input_box.context_menu and input_box.context_menu.visible:
                        # 如果有活动的右键菜单，优先处理
                        input_box.handle_event(event)
                        break
                else:
                    # 正常处理其他事件
                    result = None
                    if self.current_screen == "welcome":
                        result = self.handle_welcome_events(event)
                    elif self.current_screen == "maze_size":
                        result = self.handle_maze_size_events(event)
                    elif self.current_screen == "password":
                        result = self.handle_password_events(event)
                    elif self.current_screen == "clue_selection":
                        result = self.handle_clue_selection_events(event)
                    elif self.current_screen == "file_path":
                        result = self.handle_file_path_events(event)
                    
                    if result == "quit":
                        return None
                    elif result == "start_game":
                        return self.get_game_settings()
            
            # 更新输入框
            for input_box in self.input_boxes.values():
                input_box.update(dt)
            
            # 绘制当前界面
            if self.current_screen == "welcome":
                self.draw_welcome_screen()
            elif self.current_screen == "maze_size":
                self.draw_maze_size_screen()
            elif self.current_screen == "password":
                self.draw_password_screen()
            elif self.current_screen == "clue_selection":
                self.draw_clue_selection_screen()
            elif self.current_screen == "file_path":
                self.draw_file_path_screen()
            
            pygame.display.flip()
        
        return None
    
    def get_game_settings(self):
        """获取游戏设置"""
        if self.load_mode and self.loaded_data:
            # 从文件加载模式
            return {
                'load_mode': True,
                'loaded_data': self.loaded_data,
                'maze_size': len(self.loaded_data['maze']),
                'password': None,
                'password_hash': self.loaded_data.get('L', None),
                'all_clues': self.loaded_data.get('C', []),
                'selected_clues': self.loaded_data.get('C', [])
            }
        else:
            # 新建迷宫模式
            return {
                'load_mode': False,
                'loaded_data': None,
                'maze_size': self.maze_size,
                'password': self.password,
                'password_hash': self.password_hash,
                'all_clues': self.all_clues,
                'selected_clues': self.selected_clues
            }

def run_gui_setup():
    """运行GUI设置界面"""
    gui = GameGUI()
    settings = gui.run()
    pygame.quit()
    return settings

if __name__ == "__main__":
    settings = run_gui_setup()
    if settings:
        print("设置完成:")
        print(f"迷宫尺寸: {settings['maze_size']}")
        print(f"密码: {settings['password']}")
        print(f"选择的线索: {settings['selected_clues']}")
    else:
        print("用户取消了设置") 